/*
 * SalaBus.cpp
 *
 */

#include <sstream>
#include "SalaBus.h"
#include "Bus.h"
#include "logger/logger.h"

namespace API {

SalaBus::SalaBus(salaTypeEnum type):
		m_nonBlockingQueue("/tmp/wait_bus_queue"),
		m_requests("/tmp/wait_bus",'a'),
		m_reply("/tmp/wait_bus",'b'),
		m_doRun(true)
{
}

SalaBus::~SalaBus()
{
}

void SalaBus::init()
{
	m_nonBlockingQueue.cleanup();
	m_requests.destroy();
	m_reply.destroy();
}

void SalaBus::destroy()
{
	m_nonBlockingQueue.cleanup();
	m_requests.destroy();
	m_reply.destroy();
}

BusId SalaBus::esperarBus(SalaId nSala,Persona &persona, int &error)
{
	if(nSala < 0)
		throw Exception("N sala debe ser mayor a 0");

	std::stringstream ss;
	entryWaitRoomRequest req;
	entryWaitRoomReply rep;

	ss << "Persona "<< persona.m_id<<" entra a sala de espera:"<<nSala;

	CLogger::log(ss.str(),LogLevelEnum::INFO);

	req.m_persona.m_id = persona.m_id;

	m_requests.put(nSala, req);

	rep = m_reply.get(persona.m_id);

	ss.str("");
	ss << "Persona "<< persona.m_id<<" tiene que subir al bus:"<<rep.m_busId;

	CLogger::log(ss.str(),LogLevelEnum::INFO);

	return rep.m_busId;
}

Persona SalaBus::getPasajero(SalaId nSala)
{
	if(nSala < 0)
		throw Exception("N sala debe ser mayor a 0");

	Persona persona;

	//TODO rellenar persona, ver tema id
	waitingBusRequest busWaitReq = m_nonBlockingQueue.get(nSala);

	persona.m_id = busWaitReq.m_persona.m_id;

	return persona;
}

bool SalaBus::tienePasajeros(SalaId nSala)
{
	return !m_nonBlockingQueue.isEmpty(nSala);
}

void SalaBus::indicarBusDestino(BusId busId,Persona &persona)
{
	entryWaitRoomReply rep;

	rep.m_busId = busId;
	m_reply.put(persona.m_id,rep);
}

void SalaBus::run(SalaId nSala, BusId nBus)
{
	std::stringstream ss;
	entryWaitRoomRequest req;
	entryWaitRoomReply rep;
	waitingBusRequest busWaitReq;
	Bus bus(nBus);

	while(m_doRun)
	{
		req = m_requests.get(nSala);

		busWaitReq.m_salaId = nSala;
		busWaitReq.m_persona.m_id = req.m_persona.m_id;

		ss << "Se encola a la Persona "<< req.m_persona.m_id<<" en la espera del bus:"<<nBus;

		CLogger::log(ss.str(),LogLevelEnum::INFO);

		//TODO revisar el id con el que se rellena
		m_nonBlockingQueue.put(nSala, busWaitReq);

		bus.indicarHayPasajeros();
	}
}


}
